package com.it.rpc.core.server;

import com.alibaba.fastjson.JSON;
import com.it.rpc.IDL.user.UserResponseObj;
import com.it.rpc.core.codec.RequestBody;
import com.it.rpc.core.codec.ResponseBody;
import com.it.rpc.core.protocol.Request;
import com.it.rpc.core.protocol.Response;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import lombok.SneakyThrows;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Map;

public class RpcServerThread implements Runnable {
    private Socket accept;
    private Map<String, Object> session;

    public RpcServerThread() {
    }

    public RpcServerThread(Socket accept, Map<String, Object> session) {
        this.accept = accept;
        this.session = session;
    }

    //    @SneakyThrows
    @Override
    public void run() {
        InputStream socketInputStream = null;
        OutputStream socketOutputStream = null;

        try {
            InetAddress inetAddress = accept.getInetAddress();
            System.out.println(inetAddress + "用户连接");
            socketInputStream = accept.getInputStream();
            socketOutputStream = accept.getOutputStream();
            // 获取请求信息  header 和data
            byte[] bytes1 = new byte[1024 * 1024];
            int read = socketInputStream.read(bytes1);

            Request request = (Request) JSON.parseObject(bytes1, Request.class);
            String header = request.getHeader();
            if ("version=1".equals(header)) {
                byte[] data = request.getData();
                RequestBody requestBody = (RequestBody) JSON.parseObject(data, RequestBody.class);
                String interfaceName = requestBody.getInterfaceName();
                String methodName = requestBody.getMethodName();
                Class<?>[] parameterTypes = requestBody.getParameterTypes();
                Object[] args = requestBody.getArgs();
                // TODO 调用远程方法的响应结果
                Object object = session.get(interfaceName);
                Method method = object.getClass().getMethod(methodName, parameterTypes);
                Object invoke = method.invoke(object, args);
                // R对象

                ResponseBody responseBody = new ResponseBody();
                responseBody.setRetObject(invoke);
                byte[] userResponseByte = JSON.toJSONBytes(responseBody);
                Response response = new Response(); // 协议响应
                response.setData(userResponseByte);
                response.setHeader("version=1");
//                System.out.println("response = " + response);
                socketOutputStream.write(JSON.toJSONBytes(response));
                socketOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } finally {
            try {
                accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}
